home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src890906.arc / PATHNAME.C < prev    next >
C/C++ Source or Header  |  1989-08-19  |  2KB  |  95 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "dirutil.h"
  4.  
  5. static void crunch __ARGS((char *buf,char *path));
  6.  
  7. /* Given a working directory and an arbitrary pathname, resolve them into
  8.  * an absolute pathname. Memory is allocated for the result, which
  9.  * the caller must free
  10.  */
  11. char *
  12. pathname(cd,path)
  13. char *cd;    /* Current working directory */
  14. char *path;    /* Pathname argument */
  15. {
  16.     register char *buf;
  17.  
  18.     if(cd == NULLCHAR || path == NULLCHAR)
  19.         return NULLCHAR;
  20.  
  21.     /* Strip any leading white space on args */
  22.     while(*cd == ' ' || *cd == '\t')
  23.         cd++;
  24.     while(*path == ' ' || *path == '\t')
  25.         path++;
  26.  
  27.     /* Allocate and initialize output buffer; user must free */
  28.     buf = malloc((unsigned)strlen(cd) + strlen(path) + 10);    /* fudge factor */
  29.     if(buf == NULLCHAR)
  30.         return NULLCHAR;
  31.     buf[0] = '\0';
  32.  
  33.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  34.     if(path[0] != '/')
  35.         crunch(buf,cd);
  36.  
  37.     crunch(buf,path);
  38.  
  39.     /* Special case: null final path means the root directory */
  40.     if(buf[0] == '\0'){
  41.         buf[0] = '/';
  42.         buf[1] = '\0';
  43.     }
  44.     return buf;
  45. }
  46.  
  47. /* Process a path name string, starting with and adding to
  48.  * the existing buffer
  49.  */
  50. static void
  51. crunch(buf,path)
  52. char *buf;
  53. register char *path;
  54. {
  55.     register char *cp;
  56.     
  57.  
  58.     cp = buf + strlen(buf);    /* Start write at end of current buffer */
  59.     
  60.     /* Now start crunching the pathname argument */
  61.     for(;;){
  62.         /* Strip leading /'s; one will be written later */
  63.         while(*path == '/')
  64.             path++;
  65.         if(*path == '\0')
  66.             break;        /* no more, all done */
  67.         /* Look for parent directory references, either at the end
  68.          * of the path or imbedded in it
  69.          */
  70.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  71.             /* Hop up a level */
  72.             if((cp = strrchr(buf,'/')) == NULLCHAR)
  73.                 cp = buf;    /* Don't back up beyond root */
  74.             *cp = '\0';        /* In case there's another .. */
  75.             path += 2;        /* Skip ".." */
  76.             while(*path == '/')    /* Skip one or more slashes */
  77.                 path++;
  78.         /* Look for current directory references, either at the end
  79.          * of the path or imbedded in it
  80.          */
  81.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  82.             /* "no op" */
  83.             path++;            /* Skip "." */
  84.             while(*path == '/')    /* Skip one or more slashes */
  85.                 path++;
  86.         } else {
  87.             /* Ordinary name, copy up to next '/' or end of path */
  88.             *cp++ = '/';
  89.             while(*path != '/' && *path != '\0')
  90.                 *cp++ = *path++;
  91.         }
  92.     }
  93.     *cp++ = '\0';
  94. }
  95.